Skip to content

hrw4u: enforce sandbox policy on value functions - #13674

Open
masaori335 wants to merge 2 commits into
apache:masterfrom
masaori335:asf-master-hrw4u-lookup_function
Open

masaori335 wants to merge 2 commits into
apache:masterfrom
masaori335:asf-master-hrw4u-lookup_function

Conversation

@masaori335

Copy link
Copy Markdown
Contributor

The sandbox functions deny/warn list was only consulted for statement functions, so an entry naming a function used as a value in an expression was accepted by the loader and then silently ignored. access(), which reaches the filesystem, was among them.

The split between the two resolvers is an implementation detail; the grammar has one functionCall rule and the policy YAML exposes one functions category, so both now go through the same check.

The sandbox `functions` deny/warn list was only consulted for statement
functions, so an entry naming a function used as a value in an
expression was accepted by the loader and then silently ignored.
`access()`, which reaches the filesystem, was among them.

The split between the two resolvers is an implementation detail; the
grammar has one `functionCall` rule and the policy YAML exposes one
`functions` category, so both now go through the same check.
@masaori335 masaori335 added this to the 11.0.0 milestone Sep 14, 2026
@masaori335 masaori335 self-assigned this Sep 14, 2026
Copilot AI lite review requested due to automatic review settings September 14, 2026 07:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Address the critical interpolation denial path, moderate warning-handling issue, and documentation omission.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This pull request extends HRW4U sandbox policy enforcement to functions used as expression values.

Changes:

  • Applies deny/warn policies during value-function resolution.
  • Adds warning and denial regression fixtures.
  • Updates the sandbox schema and administrator documentation.
File summaries
File Summary
tools/hrw4u/tests/data/sandbox/warned-value-function.warning.txt Warning expectation fixture.
tools/hrw4u/tests/data/sandbox/warned-value-function.sandbox.yaml Warning policy configuration.
tools/hrw4u/tests/data/sandbox/warned-value-function.output.txt Expected warned-function output.
tools/hrw4u/tests/data/sandbox/warned-value-function.input.txt Warned value-function input case.
tools/hrw4u/tests/data/sandbox/warned-value-function.ast.txt Expected AST for the warning case.
tools/hrw4u/tests/data/sandbox/denied-value-function.sandbox.yaml Denial policy configuration.
tools/hrw4u/tests/data/sandbox/denied-value-function.input.txt Denied value-function input case.
tools/hrw4u/tests/data/sandbox/denied-value-function.error.txt Expected denial error.
tools/hrw4u/tests/data/sandbox/denied-value-function.ast.txt Expected AST for the denial case.
tools/hrw4u/src/symbols.py Enforces value-function policies; warning buffering and interpolation denial handling require changes.
tools/hrw4u/schema/sandbox.schema.json Adds value-function names to the sandbox policy schema.
doc/admin-guide/configuration/hrw4u.en.rst Documents the expanded policy, but omits two statement functions.
Review details

Suppressed comments (1)

tools/hrw4u/src/symbols.py:184

  • The policy warning is buffered before validator(args) runs. If a warned value function has invalid arguments, that validator raises and visitFunctionCall never reaches its warning drain, so the warning can be lost or attached to a later function's source context. Store the warning only after validation succeeds (while keeping the denial check before validation).
            self._collect_warning(self._sandbox.check_function(func_name))
  • Files reviewed: 12/12 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tools/hrw4u/src/symbols.py
Comment thread doc/admin-guide/configuration/hrw4u.en.rst
Both are statement functions in their own right — `set-body("x")` and
`set-body-from-file("/p")` compile — and the schema enum already accepts
them, but neither the sandbox function table nor the operator mapping
table listed them all. Both tables now match STATEMENT_FUNCTION_MAP.
Copilot AI review requested due to automatic review settings September 14, 2026 08:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No unresolved blocking issues were identified.

Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@cmcfarlen cmcfarlen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core change is right and I want it — resolve_function now runs check_function the same way resolve_statement_func does, the schema enum is exactly FUNCTION_MAP union STATEMENT_FUNCTION_MAP (21 names, checked programmatically), the doc table matches, the new fixtures are auto-collected by test_sandbox.py, and there is no double-check or double-warning since statement calls never route through resolve_function.

Holding on one thing, because it leaves the hole this PR is closing partly open:

tools/hrw4u/src/visitor.py:233 — _substitute_strings catches bare Exception, which swallows SandboxDenialError. A function that is only reached through a string interpolation — "{func()}" — therefore still escapes policy: the denial is raised, caught, and the sandbox message is never set. The new denied-value-function fixture does not catch this because access(...) fires first and the test passes for the wrong reason. Worth letting SandboxDenialError (and probably the other hrw4u error types) propagate, plus a fixture whose only denied construct is inside an interpolation.

This is the same pattern as #13675: the policy was being enforced per surface spelling rather than per semantics, so every alternate way to reach the construct is a separate bypass. Interpolation is one more alternate way.

Two smaller things while you are in here, neither blocking:

  • tools/hrw4u/src/sandbox.py:97 — functions entries are still not validated at load, unlike language and modifiers, and nothing validates the YAML against sandbox.schema.json. A misspelled function name in a policy is silently ignored, which is the same failure class this PR fixes — an operator thinks they denied something and did not. Validating against the tables would also stop schema/table drift.
  • tools/hrw4u/src/symbols.py:184 — the warning is collected before argument validation runs. If the validator raises, visitFunctionCall's trap skips _drain_resolver_warnings, so the pending warning is later attributed to an unrelated source location or dropped entirely.

Caveat: ANTLR and the antlr4 Python runtime are not available on this machine, so this was a static review — I could not run the suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants